package com.pokermind.dse.tcp.client.interactive;

import java.util.ArrayList;
import java.util.List;

/**
 * 游戏状态管理（交互式客户端本地状态）
 * 
 * @author PokerMind Interactive Client
 */
public class GameState {
    private String tableId;
    private String handId;
    private String street;         // preflop, flop, turn, river
    private int pot;
    private List<Player> players;
    private List<String> board;    // 公共牌
    private List<ActionRecord> actionHistory;
    private int currentPlayerIndex;
    private int bigBlind;
    private int smallBlind;
    
    public GameState(String tableId, int bigBlind, int smallBlind) {
        this.tableId = tableId;
        this.street = "preflop";
        this.pot = 0;
        this.players = new ArrayList<>();
        this.board = new ArrayList<>();
        this.actionHistory = new ArrayList<>();
        this.currentPlayerIndex = 0;
        this.bigBlind = bigBlind;
        this.smallBlind = smallBlind;
    }
    
    // === Core Methods ===
    
    /**
     * 添加玩家
     */
    public void addPlayer(Player player) {
        this.players.add(player);
    }
    
    /**
     * 记录行动
     */
    public void recordAction(String userId, String action, int amount) {
        ActionRecord record = new ActionRecord(userId, action, amount, street);
        actionHistory.add(record);
        
        // 更新玩家状态
        Player player = getPlayerByUserId(userId);
        if (player != null) {
            if ("fold".equals(action)) {
                player.setStatus(Player.PlayerStatus.FOLDED);
            } else if ("call".equals(action) || "raise".equals(action)) {
                player.setCurrentBet(player.getCurrentBet() + amount);
                player.setStack(player.getStack() - amount);
                pot += amount;
            }
        }
    }
    
    /**
     * 获取当前行动玩家
     */
    public Player getCurrentPlayer() {
        if (currentPlayerIndex >= 0 && currentPlayerIndex < players.size()) {
            return players.get(currentPlayerIndex);
        }
        return null;
    }
    
    /**
     * 移动到下一个玩家
     */
    public void moveToNextPlayer() {
        int attempts = 0;
        do {
            currentPlayerIndex = (currentPlayerIndex + 1) % players.size();
            attempts++;
        } while (!getCurrentPlayer().isInHand() && attempts < players.size());
    }
    
    /**
     * 根据userId查找玩家
     */
    public Player getPlayerByUserId(String userId) {
        return players.stream()
                .filter(p -> p.getUserId().equals(userId))
                .findFirst()
                .orElse(null);
    }
    
    /**
     * 检查街道是否结束（所有在局玩家注码相等）
     */
    public boolean isStreetComplete() {
        List<Player> activePlayers = getActivePlayers();
        if (activePlayers.isEmpty()) {
            return true;
        }
        
        int maxBet = activePlayers.stream()
                .mapToInt(Player::getCurrentBet)
                .max()
                .orElse(0);
        
        return activePlayers.stream()
                .allMatch(p -> p.getCurrentBet() == maxBet || p.getStatus() == Player.PlayerStatus.ALL_IN);
    }
    
    /**
     * 获取所有在局玩家
     */
    public List<Player> getActivePlayers() {
        return players.stream()
                .filter(Player::isInHand)
                .toList();
    }
    
    /**
     * 转换到下一街
     */
    public void transitionToNextStreet(List<String> newBoard) {
        // 重置当前注码
        players.forEach(p -> p.setCurrentBet(0));
        
        // 更新街道和公共牌
        this.board = new ArrayList<>(newBoard);
        
        if ("preflop".equals(street)) {
            street = "flop";
        } else if ("flop".equals(street)) {
            street = "turn";
        } else if ("turn".equals(street)) {
            street = "river";
        }
        
        // 重置到第一个在局玩家
        currentPlayerIndex = 0;
        while (!getCurrentPlayer().isInHand() && currentPlayerIndex < players.size()) {
            currentPlayerIndex++;
        }
    }
    
    /**
     * 手牌是否结束
     */
    public boolean isHandComplete() {
        return getActivePlayers().size() <= 1 || "completed".equals(street);
    }
    
    /**
     * 标记手牌完成
     */
    public void markHandComplete() {
        this.street = "completed";
    }
    
    // === Getters and Setters ===
    
    public String getTableId() { return tableId; }
    public void setTableId(String tableId) { this.tableId = tableId; }
    
    public String getHandId() { return handId; }
    public void setHandId(String handId) { this.handId = handId; }
    
    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    
    public int getPot() { return pot; }
    public void setPot(int pot) { this.pot = pot; }
    
    public List<Player> getPlayers() { return players; }
    public void setPlayers(List<Player> players) { this.players = players; }
    
    public List<String> getBoard() { return board; }
    public void setBoard(List<String> board) { this.board = board; }
    
    public List<ActionRecord> getActionHistory() { return actionHistory; }
    
    public int getCurrentPlayerIndex() { return currentPlayerIndex; }
    public void setCurrentPlayerIndex(int currentPlayerIndex) { this.currentPlayerIndex = currentPlayerIndex; }
    
    public int getBigBlind() { return bigBlind; }
    public int getSmallBlind() { return smallBlind; }
    
    /**
     * 获取最大注码
     */
    public int getMaxBet() {
        return players.stream()
                .mapToInt(Player::getCurrentBet)
                .max()
                .orElse(0);
    }
    
    /**
     * 设置当前注码（从最后一个行动获取）
     */
    public void setCurrentBet(int bet) {
        // 此方法暂时未使用，保留以兼容
    }
    
    /**
     * 添加行动到历史
     */
    public void addActionToHistory(String userId, String action, int amount) {
        recordAction(userId, action, amount);
    }
    
    /**
     * 重置街道状态（新街道开始）
     */
    public void resetForNewStreet() {
        // 重置所有玩家的当前注码
        players.forEach(p -> p.setCurrentBet(0));
        
        // 重置到第一个在局玩家
        currentPlayerIndex = 0;
        while (currentPlayerIndex < players.size() && !getCurrentPlayer().isInHand()) {
            currentPlayerIndex++;
        }
    }
    
    /**
     * 行动记录
     */
    public static class ActionRecord {
        private String userId;
        private String action;
        private int amount;
        private String street;
        
        public ActionRecord(String userId, String action, int amount, String street) {
            this.userId = userId;
            this.action = action;
            this.amount = amount;
            this.street = street;
        }
        
        public String getUserId() { return userId; }
        public String getAction() { return action; }
        public int getAmount() { return amount; }
        public String getStreet() { return street; }
    }
}

